package com.mofang.ticketing.common.core.util.map;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * 百度地图工具
 */
@Slf4j
public class BaiDuMapUtils {

    public static final String LONGITUDE_KEY = "longitude";

    public static final String LATITUDE_KEY = "latitude";

    // key
    // XPHMFN9GxxL7UMKjw5EoQIjV7wIpQ5Bd
    // jyWRSsLHc8uIbRf8EVgstpxZpMGr9LnR
    /**
     * 百度地图-API
     */
    private final static String BAI_DU_MAP_URL = "http://api.map.baidu.com/geocoder/v2/?ak=jyWRSsLHc8uIbRf8EVgstpxZpMGr9LnR&output=json";


    /**
     * 根据地址获取经纬度
     *
     * @param addr 地址
     * @return
     */
    public static Map<String, String> getLatAndLngByAddress(String addr) {
        Map<String, String> resultMap = new HashMap<>(2);
        String lat = "";
        String lng = "";
        InputStreamReader reader = null;
        BufferedReader bufferedReader = null;
        try {
            String address = String.format(BAI_DU_MAP_URL + "&address=%s", URLEncoder.encode(addr, "UTF-8"));
            URL url = new URL(address);
            URLConnection httpsConn = url.openConnection();
            if (httpsConn != null) {
                reader = new InputStreamReader(httpsConn.getInputStream(), StandardCharsets.UTF_8);
                bufferedReader = new BufferedReader(reader);
                String data;
                if ((data = bufferedReader.readLine()) != null) {
                    String status = data.substring(
                            data.indexOf("\"status\":") + ("\"status\":").length(),
                            data.indexOf("\"status\":") + ("\"status\":").length() + 1
                    );
                    if ("0".equals(status)) {
                        lat = data.substring(data.indexOf("\"lat\":")
                                + ("\"lat\":").length(), data.indexOf("},\"precise\""));
                        lng = data.substring(data.indexOf("\"lng\":")
                                + ("\"lng\":").length(), data.indexOf(",\"lat\""));
                    }
                }
            }
        } catch (Exception e) {
            log.error("根据地址获取经纬度异常", e);
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        resultMap.put(LATITUDE_KEY, lat);
        resultMap.put(LONGITUDE_KEY, lng);
        return resultMap;
    }

    /**
     * 根据经纬度获取省市区
     *
     * @param lat 纬度
     * @param lng 经度
     * @return
     */
    public static Map<String, String> getAddressByLatAndLng(String lat, String lng) {
        Map<String, String> resultMap = new HashMap<>();
        String url = String.format(BAI_DU_MAP_URL + "&location=%s", lat + "," + lng);
        try {
            String s = HttpUtil.get(url);
            JSONObject jsonObject = JSONUtil.parseObj(s);
            System.out.println(jsonObject);
            if (jsonObject != null && "0".equals(jsonObject.get("status").toString())) {
                BaiDuTheMapAddressVo baiDuTheMapAddressVo = JSONUtil.toBean(JSONUtil.toJsonStr(jsonObject.get("result")), BaiDuTheMapAddressVo.class);
                resultMap.put("country", baiDuTheMapAddressVo.getAddressComponent().getCountry());
                resultMap.put("province", baiDuTheMapAddressVo.getAddressComponent().getProvince());
                resultMap.put("city", baiDuTheMapAddressVo.getAddressComponent().getCity());
                resultMap.put("county", baiDuTheMapAddressVo.getAddressComponent().getDistrict());
            }
            return resultMap;
        } catch (Exception e) {
            log.error("根据经纬度获取省市区", e);
        }
        return null;
    }

    public static void main(String[] args) {
        String address = "广东省,深圳市,福田区".replace(",", "") + "车公庙泰然工业区";
        System.out.println(address);

        Map<String, String> latAndLngByAddressMap = BaiDuMapUtils.getLatAndLngByAddress(address);
        System.out.println(address + "纬度：" + latAndLngByAddressMap);
        Map<String, String> addressByLatAndLng = getAddressByLatAndLng(latAndLngByAddressMap.get(LATITUDE_KEY), latAndLngByAddressMap.get(LONGITUDE_KEY));
        System.out.println("地址：" + addressByLatAndLng);
    }

    @Data
    public static class BaiDuTheMapAddressVo implements Serializable {

        private static final long serialVersionUID = -1810326019680109173L;

        private Location location;
        private String formatted_address;
        private String business;
        private AddressComponent addressComponent;


        @Data
        public static class Location {
            private String lng;
            private String lat;
        }

        @Data
        public static class AddressComponent {
            private String country;
            private int country_code;
            private String country_code_iso;
            private String country_code_iso2;
            private String province;
            private String city;
            private int city_level;
            private String district;
            private String town;
            private String town_code;
            private String adcode;
            private String street;
            private String street_number;
            private String direction;
            private String distance;
        }

    }

}
